#ifndef _NES_H
#define _NES_H

#include "cpu.h"
#include "ppu.h"
#include "joypad.h"
#include "video_memory.h"
#include "nes_config.h"

#include <stdio.h>

typedef void (*DrawFrame)();
class CNes
{
public:
                  CNes(DrawFrame draw);
                  ~CNes();

public:
  void            Init();
  void            Reset();
  void            Step();

  void            Run();
  void            Stop();
  bool            Running();
  void            NMIReq();

  // h-sync
  void            HSync();

  // mem & reg
  u8              ReadByte(u16 addr);
  u16             ReadWord(u16 addr);
  void            Write(u16 addr, u8 data);
  u8              ReadPort(u16 port);
  void            WritePort(u16 port, u8 data);
  void            DMA(u16 data);

  // rom
public:
  bool            LoadRom(wchar_t* RomFile);
  u8*             GetPatternTbl(int index = 0);
  u8*             GetNameTbl(int index = 0);
  u8*             GetAttribTbl(int index = 0);

  // ppu
public:
  u16*            GetPatternImage();
  u16*            GetNameTblImage();
  u16*            GetSpriteImage();
  u16*            GetFrame();
  u16*            GetFinalFrame();
  u8*             GetBGPalette();
  u8*             GetSPPalette();

  // Joypad
  void            SetKeyState(int index, u8 key, u8 down);

private:
  NesHeader       m_Header;
  DrawFrame       m_FuncDrawFrame;

public:
  CCpu*           m_Cpu;
  CPpu*           m_Ppu;
  CJoyPad*        m_JoyPad;
  CVideoMemory*   m_VideoMemory;
  int             m_Scanlines;
  bool            m_StopEmu;
  int             m_MapperNo;
};
extern CNes* g_NES;

#endif  // _NES_H
